﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using generic_class;


namespace pallete_main
{

    //设备类型
    public enum _device_type
    {
        DT_IM = 0,
        DT_OTHER,
        DT_ROUTER,
    }

    public enum _line_direction
    {
        LD_LEFT = 0,//横图象左
        LD_RIGHT, //横图向右
        LD_DOWN, //纵图向下
        LD_UP, //纵图像上
    }

    public enum _line_type
    {

        LT_ONE = 0,//类型1，相同设备间可以是im/im ,other/other
        LT_IM_OTHER, //类型2，IM/OTHER之间
        LT_ROUTHER //类型3，im或者other和router
    }

    public class _layout_item
    {
        //设备起始坐标
        public Point2d ptStart;
        //设备宽度
        public int nWidth;
        //设备长度
        public int nHeight;

        //已经画的线段,每个设备最多两根线
        public int nLineCount;
    }


    //划线的类型
    public struct _line_item
    {
        public _device_type start_type;        //起始端设备类型
        public int nStartDevice ;               //起始端设备在列表中的位置,从1开始标号
        public _device_type end_type;          //结束端设备类型
        public int nEndDevice;                 //结束段设备在列表中的位置,1开始
    }


    //线段信息
    public struct _polyline_item
    {
        public ArrayList ptList;
    }

    class module_layout
    {
        //路由器列表
        private ArrayList m_lstRouter = new ArrayList();

        //I,M类型设备列表,
        //竖向出图位于左侧，横向出图位于上侧
        private ArrayList m_lstIMDevice= new ArrayList();

        //其他类型设备列表
        //竖向出图位于右侧，横向出图位于下侧
        private ArrayList m_lstOtherDevice = new ArrayList();

        //设备间默认间隔
        private int m_nDeletaDevice = 20;
        
        //设备和路由之间默认间隔
        private int m_nDeletaWithRouter = 100;

        //连线之间的间距
        private int m_nDeletaLine = 10;

        //图坐标中心,以第一个路由设备起始坐标为中心
        private Point3d m_pOffset = new Point3d(1500, 800, 0);

        //设备图形默认宽度和高度,注意区分横向和纵向图
        //宽度和高度是相反的 
        private int m_nDefaultWidth = 100;
        private int m_nDefaultHeight = 30;

        //字体
        public int m_nDefaultFont = 20;

        //方向
        _direction m_direction = _direction.TABLE_VER;

        //四个参数分别表示目前连线的最大范围的宽度
        //的四个角
        Point2d m_ptUperLeft = new Point2d(0,0);
        Point2d m_ptUperRight = new Point2d(0,0);
        Point2d m_ptLowLeft = new Point2d(0,0);
        Point2d m_ptLowRight = new Point2d(0, 0);

        //Polyline list
        private ArrayList m_lstPolyline = new ArrayList();

        //计算线的方向 ,根据输入的坐标
        private _line_direction CalDirection(Point2d pt)
        {

            //取路由设备的区域计算
            int nCount = m_lstIMDevice.Count;//m_lstRouter.Count;
            _layout_item item = (_layout_item)m_lstIMDevice[nCount - 1];
            if(m_direction == _direction.TABLE_HOR)
            {
                //横图计算,超过路由设备的一半，向左走线
                //否则向右走线
                if (pt.X > ((item.ptStart.X + item.nWidth) / 2))
                    return _line_direction.LD_RIGHT;
                else
                    return _line_direction.LD_LEFT;
            }
            else
            {
                //纵图计算,大于y坐标的一半，向上走线，否则向下
                //走线
                if (pt.Y > ((item.ptStart.Y - item.nHeight) / 2))
                    return _line_direction.LD_UP;
                else
                    return _line_direction.LD_DOWN;
            }
        }
        //根据3种设备自动计算初始最大区域
        private bool FindMaxErea()
        {

            int nRouterCount = m_lstRouter.Count;
            int nIMCount = m_lstIMDevice.Count;
            int nOtherCount = m_lstOtherDevice.Count;
            _layout_item bounder_item = null;//区域的横图右边或者纵图最下边的边界


            //没有设备或者数量是0，返回失败
            if ((m_lstRouter == null) &&
                (m_lstIMDevice == null) &&
                (m_lstOtherDevice == null))
                return false;

            if ((m_lstRouter.Count == 0) &&
                (m_lstIMDevice.Count == 0) &&
                (m_lstOtherDevice.Count == 0))
                 return false;

            //找到最多的设备，决定区域的长度或者高度
            if((nRouterCount >= nIMCount) && (nRouterCount >= nOtherCount))
            {
                //路由设备最多，取路由设备的区域作为边界
                bounder_item = (_layout_item)m_lstRouter[nRouterCount - 1];
            }
            else
            {
                //im 或者 other设备最多
                if (nIMCount >= nOtherCount)
                    bounder_item = (_layout_item)m_lstIMDevice[nIMCount - 1];
                else
                    bounder_item = (_layout_item)m_lstOtherDevice[nOtherCount - 1];
            }

            //计算四个角的位置
            if (m_direction == _direction.TABLE_HOR)
            {//横向出图

                //横向图m_ptUperLeft 等于第一个other设备
                //起始左上角坐标
                _layout_item item = (_layout_item)m_lstOtherDevice[0];
                _layout_item im_item = (_layout_item)m_lstIMDevice[0];
                m_ptUperLeft = item.ptStart;
                m_ptUperRight = new Point2d(bounder_item.ptStart.X + bounder_item.nWidth, m_ptUperLeft.Y);
                m_ptLowLeft = new Point2d(m_ptUperLeft.X, im_item.ptStart.Y - im_item.nHeight);
                m_ptLowRight = new Point2d(m_ptUperRight.X,m_ptLowLeft.Y);
            }
            else
            {
                //纵向图m_ptUperLeft 等于第一个im设备
                //起始左上角坐标
                _layout_item item = (_layout_item)m_lstIMDevice[0];
                _layout_item other_item = (_layout_item)m_lstOtherDevice[0];
                m_ptUperLeft = item.ptStart;
                m_ptUperRight = new Point2d(other_item.ptStart.X + other_item.nWidth,m_ptUperLeft.Y);
                m_ptLowLeft = new Point2d(m_ptUperLeft.X,bounder_item.ptStart.Y - bounder_item.nHeight);
                m_ptLowRight = new Point2d(m_ptUperRight.X, m_ptLowLeft.Y);
            }

            return true;
        }

        //画第一种类型线段相同设备之间.
        //im/im or other/other,划线函数为了计算方便
        //横图统一从左到右计算，纵图统一从上到下计算
        private bool DrawLinesOne(_device_type type, int nStart,int nEnd)
        {
            _layout_item start_item = null;
            _layout_item end_item = null;
            _polyline_item pl_item =  new _polyline_item();

            if(nStart == nEnd)
            {
                System.Windows.Forms.MessageBox.Show("不能设备连接自己");
                return false;
            }

            if (type == _device_type.DT_IM)
            {

                if (nStart > nEnd)
                {
                    start_item = (_layout_item)m_lstIMDevice[nEnd];
                    end_item = (_layout_item)m_lstIMDevice[nStart];
                }
                else
                {
                    start_item = (_layout_item)m_lstIMDevice[nStart];
                    end_item = (_layout_item)m_lstIMDevice[nEnd];
                }



            }
            else if (type == _device_type.DT_OTHER)
            {
                 if (nStart > nEnd)
                {
                    start_item = (_layout_item)m_lstOtherDevice[nEnd];
                    end_item = (_layout_item)m_lstOtherDevice[nStart];
                }
                else
                {
                    start_item = (_layout_item)m_lstOtherDevice[nStart];
                    end_item = (_layout_item)m_lstOtherDevice[nEnd];
                }

            }

            if ((start_item.nLineCount == 2) || (end_item.nLineCount == 2))
            {
               // System.Windows.Forms.MessageBox.Show("设备连线超过两条");
                return false;
            }

            pl_item.ptList = new ArrayList();
            
            if (m_direction == _direction.TABLE_HOR)
            {
                int nX = 0;
                int nY = 0;
                int nLineCount = start_item.nLineCount + 1;
                int nEndLineCount = end_item.nLineCount + 1;

                if (type == _device_type.DT_OTHER)
                {
                    //计算polyline的点，1型线段固定是4个点
                    //计算第一个点
                    //other 设备
                    nX = (int)(start_item.ptStart.X + (start_item.nWidth / 3) * nLineCount);
                    nY = (int)start_item.ptStart.Y;
                    pl_item.ptList.Add(new Point2d(nX,nY));

                    //计算第二个点
                    nY = (int)(m_ptUperLeft.Y + m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX,nY));
                    //更新边界
                    m_ptUperLeft += new Vector2d(0, m_nDeletaLine);
                    m_ptUperRight += new Vector2d(0, m_nDeletaLine);

                    //计算第三个点
                    nX = (int)(end_item.ptStart.X + (end_item.nWidth / 3) * nEndLineCount);
                    pl_item.ptList.Add(new Point2d(nX,nY));

                    //计算第四个点
                    nY = (int)end_item.ptStart.Y;
                    pl_item.ptList.Add(new Point2d(nX,nY));

                }
                else
                {
                    //im设备
                    nX = (int)(start_item.ptStart.X + (start_item.nWidth / 3) * nLineCount);
                    nY = (int)start_item.ptStart.Y - start_item.nHeight;
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    //计算第二个点
                    nY = (int)(m_ptLowLeft.Y - m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));
                    //更新边界
                    m_ptLowLeft += new Vector2d(0, -m_nDeletaLine);
                    m_ptLowRight += new Vector2d(0, -m_nDeletaLine);

                    //计算第三个点
                    nX = (int)(end_item.ptStart.X + (end_item.nWidth / 3) * nEndLineCount);
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    //计算第四个点
                    nY = (int)(end_item.ptStart.Y - end_item.nHeight);
                    pl_item.ptList.Add(new Point2d(nX, nY));

                }

            }
            else
            {
                int nX = 0;
                int nY = 0;
                int nLineCount = start_item.nLineCount + 1;
                int nEndLineCount = end_item.nLineCount + 1;

                if (type == _device_type.DT_OTHER)
                {
                    //计算polyline的点，1型线段固定是4个点
                    //计算第一个点
                    //other 设备
                    nX = (int)(start_item.ptStart.X + start_item.nWidth);
                    nY = (int)(start_item.ptStart.Y - (start_item.nHeight / 3) * nLineCount);
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    //计算第二个点
                    nX = (int)(m_ptUperRight.X + m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));
                    //更新边界
                    m_ptUperRight += new Vector2d(m_nDeletaLine,0);
                    m_ptLowRight += new Vector2d(m_nDeletaLine,0);

                    //计算第三个点
                    nY = (int)(end_item.ptStart.Y - (end_item.nHeight / 3) * nEndLineCount);
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    //计算第四个点
                    nX = (int)(end_item.ptStart.X + end_item.nWidth);
                    pl_item.ptList.Add(new Point2d(nX, nY));
                }
                else
                {
                    //im to im
                    nX = (int)(start_item.ptStart.X );
                    nY = (int)(start_item.ptStart.Y - (start_item.nHeight / 3) * nLineCount);
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    //计算第二个点
                    nX = (int)(m_ptUperLeft.X - m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));
                    //更新边界
                    m_ptUperLeft += new Vector2d(-m_nDeletaLine, 0);
                    m_ptLowLeft += new Vector2d(-m_nDeletaLine, 0);

                    //计算第三个点
                    nY = (int)(end_item.ptStart.Y - (end_item.nHeight / 3) * nEndLineCount);
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    //计算第四个点
                    nX = (int)(end_item.ptStart.X );
                    pl_item.ptList.Add(new Point2d(nX, nY));

                }

            }

            //线段数量增加 
            start_item.nLineCount++;
            end_item.nLineCount++;

            m_lstPolyline.Add(pl_item);
            return true;
        }

        //固定从im画图到other设备
        private bool DrawLinesTwo(int nStart, int nEnd)
        {

            _layout_item start_item = null;
            _layout_item end_item = null;
            _polyline_item pl_item = new _polyline_item();
            int nX = 0;
            int nY = 0;


            if ((nStart >= m_lstIMDevice.Count) || (nEnd >= m_lstOtherDevice.Count))
            {
                System.Windows.Forms.MessageBox.Show("连接设备不存在");
                return false;
            }

            start_item =(_layout_item)m_lstIMDevice[nStart];
            end_item = (_layout_item)m_lstOtherDevice[nEnd];
            pl_item.ptList = new ArrayList();
            int nLineCount = start_item.nLineCount + 1;
            int nEndLineCount = end_item.nLineCount + 1;

            //2型曲线固定6个点
            if(m_direction == _direction.TABLE_HOR)
            {
                _line_direction direction;
                //横图
                //计算第一个点
                nX = (int)(start_item.ptStart.X + (start_item.nWidth / 3) * nLineCount);
                nY = (int)start_item.ptStart.Y - start_item.nHeight;
                pl_item.ptList.Add(new Point2d(nX, nY));

                //计算第二个点
                nY = (int)(m_ptLowLeft.Y - m_nDeletaLine);
                pl_item.ptList.Add(new Point2d(nX, nY));
                //更新边界
                m_ptLowLeft += new Vector2d(0, -m_nDeletaLine);
                m_ptLowRight += new Vector2d(0, -m_nDeletaLine);

                //计算第三个点的方向 
                direction = CalDirection(new Point2d(nX,nY));
                if (direction == _line_direction.LD_LEFT)
                {
                    //左向走线,第三个点 
                    nX = (int)(m_ptLowLeft.X - m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));
                    //更新边界
                    m_ptLowLeft += new Vector2d(-m_nDeletaLine,0);
                    m_ptUperLeft += new Vector2d(-m_nDeletaLine,0);

                    //计算第四个点
                    nY = (int)(m_ptUperLeft.Y + m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));
                    //更新边界
                    m_ptUperRight += new Vector2d(0,m_nDeletaLine);
                    m_ptUperLeft += new Vector2d(0,m_nDeletaLine);

                    //计算第五个点
                    nX = (int)(end_item.ptStart.X + (end_item.nWidth / 3) * nEndLineCount);
                    pl_item.ptList.Add(new Point2d(nX, nY));


                    //计算第六个点
                    nY = (int)end_item.ptStart.Y;
                    pl_item.ptList.Add(new Point2d(nX, nY));

                }
                else
                {
                    //右向走线,第三个点 
                    nX = (int)(m_ptLowRight.X + m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));
                    //更新边界
                    m_ptLowRight += new Vector2d(m_nDeletaLine, 0);
                    m_ptUperRight += new Vector2d(m_nDeletaLine, 0);

                    //计算第四个点
                    nY = (int)(m_ptUperLeft.Y + m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));
                    //更新边界
                    m_ptUperRight += new Vector2d(0, m_nDeletaLine);
                    m_ptUperLeft += new Vector2d(0, m_nDeletaLine);

                    //计算第五个点
                    nX = (int)(end_item.ptStart.X + (end_item.nWidth / 3) * nEndLineCount);
                    pl_item.ptList.Add(new Point2d(nX, nY));


                    //计算第六个点
                    nY = (int)end_item.ptStart.Y;
                    pl_item.ptList.Add(new Point2d(nX, nY));


                }

            }
            else
            {
                 _line_direction direction;
                //纵图
                //计算第一个点
                nX = (int)(start_item.ptStart.X );
                nY = (int)(start_item.ptStart.Y - start_item.nHeight/2);
                pl_item.ptList.Add(new Point2d(nX, nY));

                //计算第二个点
                nX = (int)(m_ptLowLeft.X - m_nDeletaLine);
                pl_item.ptList.Add(new Point2d(nX, nY));
                //更新边界
                m_ptLowLeft += new Vector2d(-m_nDeletaLine,0);
                m_ptUperLeft += new Vector2d(-m_nDeletaLine,0);


                //计算第三个点的方向 
                direction = CalDirection(new Point2d(nX,nY));
                if (direction == _line_direction.LD_UP)
                {
                    //向上走线
                    //左向走线,第三个点 
                    nY = (int)(m_ptUperLeft.Y + m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));
                    //更新边界
                    m_ptUperRight += new Vector2d(0,m_nDeletaLine);
                    m_ptUperLeft += new Vector2d(0,m_nDeletaLine);

                    //计算第四个点
                    nX = (int)(m_ptUperRight.X + m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    //更新边界
                    m_ptUperRight += new Vector2d(m_nDeletaLine,0);
                    m_ptLowRight += new Vector2d(m_nDeletaLine,0);

                    //计算第五个点
                    nY = (int)(end_item.ptStart.Y - (end_item.nHeight / 3) * nEndLineCount);
                    pl_item.ptList.Add(new Point2d(nX, nY));


                    //计算第六个点
                    nX = (int)end_item.ptStart.X + end_item.nWidth;
                    pl_item.ptList.Add(new Point2d(nX, nY));


                }
                else
                {
                    //向下走线
                    //左向走线,第三个点 
                    nY = (int)(m_ptLowLeft.Y - m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));
                    //更新边界
                    m_ptLowRight += new Vector2d(0, -m_nDeletaLine);
                    m_ptLowLeft += new Vector2d(0, -m_nDeletaLine);

                    //计算第四个点
                    nX = (int)(m_ptLowRight.X + m_nDeletaLine);
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    //更新边界
                    m_ptUperRight += new Vector2d(m_nDeletaLine, 0);
                    m_ptLowRight += new Vector2d(m_nDeletaLine, 0);

                    //计算第五个点
                    nY = (int)(end_item.ptStart.Y - (end_item.nHeight / 3) * nEndLineCount);
                    pl_item.ptList.Add(new Point2d(nX, nY));


                    //计算第六个点
                    nX = (int)end_item.ptStart.X + end_item.nWidth;
                    pl_item.ptList.Add(new Point2d(nX, nY));


                }
            }

            start_item.nLineCount++;
            end_item.nLineCount++;

            m_lstPolyline.Add(pl_item);
            return true;
        }

        //固定从im/other画图到router设备,nEnd目前没有启动，
        //根据设备对应位置自动计算所属路由器
        private bool DrawLinesThree(_device_type type, int nStart, int nEnd)
        {
            _layout_item start_item = null;
            _layout_item end_item = null;
            _polyline_item pl_item = new _polyline_item();
            int nX = 0;
            int nY = 0;

            if((nEnd >= m_lstRouter.Count))
            {
                System.Windows.Forms.MessageBox.Show("路由设备不存在");
                return false;
            }

            end_item = (_layout_item)m_lstRouter[nEnd];
            pl_item.ptList = new ArrayList();

            if (m_direction == _direction.TABLE_HOR)
            {
                //横图
                if (type == _device_type.DT_IM)
                {
                    //im to router
                    if (nStart >= m_lstIMDevice.Count)
                    {
                        System.Windows.Forms.MessageBox.Show("IM设备不存在");
                        return false;
                    }

                    start_item = (_layout_item)m_lstIMDevice[nStart];

                    //两个点
                    //im设备
                    nX = (int)(start_item.ptStart.X + (start_item.nWidth / 2));
                    nY = (int)start_item.ptStart.Y ;
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    nY = (int)start_item.ptStart.Y + m_nDeletaWithRouter;
                    pl_item.ptList.Add(new Point2d(nX, nY));

                }
                else
                {
                    //other to router
                    if (nStart >= m_lstOtherDevice.Count)
                    {
                        System.Windows.Forms.MessageBox.Show("other设备不存在");
                        return false;
                    }
                    start_item = (_layout_item)m_lstOtherDevice[nStart];

                    //两个点
                    //other设备
                    nX = (int)(start_item.ptStart.X + (start_item.nWidth / 2));
                    nY = (int)start_item.ptStart.Y - start_item.nHeight;
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    nY = (int)start_item.ptStart.Y - m_nDeletaWithRouter - start_item.nHeight;
                    pl_item.ptList.Add(new Point2d(nX, nY));

                }
            }
            else
            {
                //纵图
                if (type == _device_type.DT_IM)
                {
                    //im to router
                    if (nStart >= m_lstIMDevice.Count)
                    {
                        System.Windows.Forms.MessageBox.Show("IM设备不存在");
                        return false;
                    }

                    start_item = (_layout_item)m_lstIMDevice[nStart];

                    //两个点
                    //im设备
                    nX = (int)(start_item.ptStart.X + start_item.nWidth);
                    nY = (int)(start_item.ptStart.Y - start_item.nHeight/2);
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    nX = 0;
                    pl_item.ptList.Add(new Point2d(nX, nY));

                }
                else
                {
                    //other to router
                    if (nStart >= m_lstOtherDevice.Count)
                    {
                        System.Windows.Forms.MessageBox.Show("other设备不存在");
                        return false;
                    }
                    start_item = (_layout_item)m_lstOtherDevice[nStart];

                    //两个点
                    //other设备
                    nX = (int)(start_item.ptStart.X );
                    nY = (int)(start_item.ptStart.Y - start_item.nHeight/2);
                    pl_item.ptList.Add(new Point2d(nX, nY));

                    nX = nX - m_nDeletaWithRouter;
                    pl_item.ptList.Add(new Point2d(nX, nY));

                }

            }

            m_lstPolyline.Add(pl_item);
            return true;
        }

        public bool DrawLines(ArrayList line_array)
        {
            int nCount = 0;
            if ((line_array == null) || (line_array.Count == 0))
            {
                System.Windows.Forms.MessageBox.Show("线参数输入错误");
            }
            CalateLayout(3, 5, 9);

            if(false == FindMaxErea())
                System.Windows.Forms.MessageBox.Show("计算初始最大区域错误");

            //画每条线
            for (nCount = 0; nCount < line_array.Count; nCount++)
            {
                _line_item item = (_line_item)line_array[nCount]; 

                //im/im or other/other,1型线段
                if(((item.start_type == _device_type.DT_IM) && (item.end_type == _device_type.DT_IM)) ||
                    ((item.start_type == _device_type.DT_OTHER) && (item.end_type == _device_type.DT_OTHER)))
                {
                    DrawLinesOne(item.start_type, item.nStartDevice, item.nEndDevice);
                }


                //2型线段
                if (((item.start_type == _device_type.DT_IM) && (item.end_type == _device_type.DT_OTHER)))
                {
                    DrawLinesTwo(item.nStartDevice, item.nEndDevice);
                }

                //2型线段
                if (((item.start_type == _device_type.DT_OTHER) && (item.end_type == _device_type.DT_IM)))
                {
                    DrawLinesTwo(item.nEndDevice, item.nStartDevice);
                }

                //3型线段
                if (((item.start_type == _device_type.DT_IM) && (item.end_type == _device_type.DT_ROUTER)))
                {
                    DrawLinesThree(_device_type.DT_IM, item.nStartDevice, 0);
                }

                //3型线段
                if (((item.start_type == _device_type.DT_ROUTER) && (item.end_type == _device_type.DT_IM)))
                {
                    DrawLinesThree(_device_type.DT_IM, item.nEndDevice, 0);
                }

                //3型线段
                if (((item.start_type == _device_type.DT_OTHER) && (item.end_type == _device_type.DT_ROUTER)))
                {
                    DrawLinesThree(_device_type.DT_OTHER, item.nStartDevice, 0);
                }

                if (((item.start_type == _device_type.DT_ROUTER) && (item.end_type == _device_type.DT_OTHER)))
                {
                    DrawLinesThree(_device_type.DT_OTHER, item.nEndDevice, 0);
                }

            }


            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;

            acDoc.LockDocument();

            // 启动一个事务  Start a transaction
            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                // 以只读方式打开块表   Open the Block table for read
                BlockTable acBlkTbl;
                int index = 0;
                acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
                                             OpenMode.ForRead) as BlockTable;

                // 以写方式打开模型空间块表记录   Open the Block table record Model space for write
                BlockTableRecord acBlkTblRec;
                acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
                                                OpenMode.ForWrite) as BlockTableRecord;


                //画路由器设备
                for (index = 0; index < m_lstRouter.Count; index++)
                {
                    _layout_item item = (_layout_item)m_lstRouter[index];
                    Point2d pt = item.ptStart + new Vector2d(m_pOffset.X, m_pOffset.Y);

                    Table tbl = new Table();
                    tbl.TableStyle = acCurDb.Tablestyle;
                    tbl.NumRows = 1;
                    tbl.NumColumns = 1;
                    tbl.Position = new Point3d(pt.X, pt.Y, 0);
                    tbl.SetColumnWidth(item.nWidth);
                    tbl.SetRowHeight(item.nHeight);
                    tbl.SetTextHeight(0, 0, m_nDefaultFont);
                    tbl.SetTextString(0, 0, "路由器");

                    acBlkTblRec.AppendEntity(tbl);
                    acTrans.AddNewlyCreatedDBObject(tbl, true);

                }

                //画im设备
                for (index = 0; index < m_lstIMDevice.Count; index++)
                {
                    _layout_item item = (_layout_item)m_lstIMDevice[index];
                    Point2d pt = item.ptStart + new Vector2d(m_pOffset.X, m_pOffset.Y);

                    Table tbl = new Table();
                    tbl.TableStyle = acCurDb.Tablestyle;
                    tbl.NumRows = 1;
                    tbl.NumColumns = 1;
                    tbl.Position = new Point3d(pt.X, pt.Y, 0);
                    tbl.SetColumnWidth(item.nWidth);
                    tbl.SetRowHeight(item.nHeight);
                    tbl.SetTextHeight(0, 0, m_nDefaultFont);
                    tbl.SetTextString(0, 0, "IM设备");

                    acBlkTblRec.AppendEntity(tbl);
                    acTrans.AddNewlyCreatedDBObject(tbl, true);

                }

                //画其他设备
                for (index = 0; index < m_lstOtherDevice.Count; index++)
                {
                    _layout_item item = (_layout_item)m_lstOtherDevice[index];
                    Point2d pt = item.ptStart + new Vector2d(m_pOffset.X, m_pOffset.Y);

                    Table tbl = new Table();
                    tbl.TableStyle = acCurDb.Tablestyle;
                    tbl.NumRows = 1;
                    tbl.NumColumns = 1;
                    tbl.Position = new Point3d(pt.X, pt.Y, 0);
                    tbl.SetColumnWidth(item.nWidth);
                    tbl.SetRowHeight(item.nHeight);
                    tbl.SetTextHeight(0, 0, m_nDefaultFont);
                    tbl.SetTextString(0, 0, "其他设备");

                    acBlkTblRec.AppendEntity(tbl);
                    acTrans.AddNewlyCreatedDBObject(tbl, true);

                }


                //画线
                for (index = 0; index < m_lstPolyline.Count; index++)
                {
                    _polyline_item item = (_polyline_item)m_lstPolyline[index];
                    Polyline pl_line = null;
                    if (item.ptList.Count <= 0)
                        continue;

                    pl_line = new Polyline();
                    for (int nPtCount = 0; nPtCount < item.ptList.Count; nPtCount++)
                    {
                        Point2d pt = (Point2d)item.ptList[nPtCount] + new Vector2d(m_pOffset.X, m_pOffset.Y);
                        pl_line.AddVertexAt(nPtCount, pt, 0, 0, 0);
                    }

                    acBlkTblRec.AppendEntity(pl_line);
                    acTrans.AddNewlyCreatedDBObject(pl_line, true);

                }

                acTrans.Commit();
            }

            return true;

        }

        public bool DrawLayout()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;
            CalateLayout(3, 5, 9);

            acDoc.LockDocument();

            // 启动一个事务  Start a transaction
            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                // 以只读方式打开块表   Open the Block table for read
                BlockTable acBlkTbl;
                int index = 0;
                acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
                                             OpenMode.ForRead) as BlockTable;

                // 以写方式打开模型空间块表记录   Open the Block table record Model space for write
                BlockTableRecord acBlkTblRec;
                acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
                                                OpenMode.ForWrite) as BlockTableRecord;


                //画路由器设备
                for (index = 0; index < m_lstRouter.Count; index++)
                {
                    _layout_item item = (_layout_item)m_lstRouter[index];
                    Point2d pt = item.ptStart + new Vector2d(m_pOffset.X, m_pOffset.Y);

                    Table tbl = new Table();
                    tbl.TableStyle = acCurDb.Tablestyle;
                    tbl.NumRows = 1;
                    tbl.NumColumns = 1;
                    tbl.Position = new Point3d(pt.X, pt.Y, 0);
                    tbl.SetColumnWidth(item.nWidth);
                    tbl.SetRowHeight(item.nHeight);
                    tbl.SetTextHeight(0, 0, m_nDefaultFont);
                    tbl.SetTextString(0, 0, "路由器");

                    acBlkTblRec.AppendEntity(tbl);
                    acTrans.AddNewlyCreatedDBObject(tbl, true);

                }

                //画im设备
                for (index = 0; index < m_lstIMDevice.Count; index++)
                {
                    _layout_item item = (_layout_item)m_lstIMDevice[index];
                    Point2d pt = item.ptStart + new Vector2d(m_pOffset.X, m_pOffset.Y);

                    Table tbl = new Table();
                    tbl.TableStyle = acCurDb.Tablestyle;
                    tbl.NumRows = 1;
                    tbl.NumColumns = 1;
                    tbl.Position = new Point3d(pt.X, pt.Y, 0);
                    tbl.SetColumnWidth(item.nWidth);
                    tbl.SetRowHeight(item.nHeight);
                    tbl.SetTextHeight(0, 0, m_nDefaultFont);
                    tbl.SetTextString(0, 0, "IM设备");

                    acBlkTblRec.AppendEntity(tbl);
                    acTrans.AddNewlyCreatedDBObject(tbl, true);

                }

                //画其他设备
                for (index = 0; index < m_lstOtherDevice.Count; index++)
                {
                    _layout_item item = (_layout_item)m_lstOtherDevice[index];
                    Point2d pt = item.ptStart + new Vector2d(m_pOffset.X, m_pOffset.Y);

                    Table tbl = new Table();
                    tbl.TableStyle = acCurDb.Tablestyle;
                    tbl.NumRows = 1;
                    tbl.NumColumns = 1;
                    tbl.Position = new Point3d(pt.X, pt.Y, 0);
                    tbl.SetColumnWidth(item.nWidth);
                    tbl.SetRowHeight(item.nHeight);
                    tbl.SetTextHeight(0, 0, m_nDefaultFont);
                    tbl.SetTextString(0, 0, "其他设备");

                    acBlkTblRec.AppendEntity(tbl);
                    acTrans.AddNewlyCreatedDBObject(tbl, true);

                }

                acTrans.Commit();
            }

            return true;
        }
        //根据输入路由以及设备数量计算各自的位置
        //输入路由器设备数量，im设备数量，其他类型设备数量 
        private bool CalateLayout(int nRouterCount, int nCountIM, int nCountOther)
        {

            Point2d ptStart = new Point2d(0, 0);

            //首先找出最多的设备，计算图形最大长度和宽度
            //计算以第一个路由器坐上为原点，最后用m_poffset修正
            if ((nRouterCount >= nCountIM) && (nRouterCount >= nCountOther))
            {//路由器数量最多

                int index = 0;

                for (index = 0; index < nRouterCount; index++)
                {
                    _layout_item item = new _layout_item();

                    if (m_direction == _direction.TABLE_HOR)
                    {//横向出图
                        item.ptStart = ptStart;
                        item.nWidth = m_nDefaultWidth;
                        item.nHeight = m_nDefaultHeight;
                        ptStart += new Vector2d(m_nDefaultWidth + m_nDeletaDevice, 0);
                    }
                    else
                    {
                        //纵向出图，宽高相反
                        item.ptStart = ptStart;
                        item.nWidth = m_nDefaultHeight;
                        item.nHeight = m_nDefaultWidth;
                
                        ptStart -= new Vector2d(0,m_nDefaultWidth + m_nDeletaDevice);
                    }

                    m_lstRouter.Add(item);
                }

                for (index = 0; index < nCountOther; index++)
                {
                    _layout_item item = new _layout_item();
                    _layout_item route_item = (_layout_item)m_lstRouter[index];
                    Point2d pt = route_item.ptStart;

                    if (m_direction == _direction.TABLE_HOR)
                    {//横向出图

                        item.ptStart = new Point2d(pt.X, pt.Y + m_nDeletaWithRouter);
                        item.nHeight = route_item.nHeight;
                        item.nWidth = route_item.nWidth;
                    }
                    else
                    {
                        //纵向出图，宽高相反
                        item.ptStart = new Point2d(pt.X - m_nDeletaWithRouter, pt.Y);
                        item.nHeight = route_item.nHeight;
                        item.nWidth = route_item.nWidth;
                    }
                    m_lstOtherDevice.Add(item);
                }

                for (index = 0; index < nCountIM; index++)
                {
                    _layout_item item = new _layout_item();
                    _layout_item route_item = (_layout_item)m_lstRouter[index];
                    Point2d pt = route_item.ptStart;

                    if (m_direction == _direction.TABLE_HOR)
                    {//横向出图

                        item.ptStart = new Point2d(pt.X, pt.Y - m_nDeletaWithRouter);
                        item.nHeight = route_item.nHeight;
                        item.nWidth = route_item.nWidth;
                    }
                    else
                    {
                        //纵向出图，宽高相反
                        item.ptStart = new Point2d(pt.X + m_nDeletaWithRouter, pt.Y);
                        item.nHeight = route_item.nHeight;
                        item.nWidth = route_item.nWidth;
                    }
                    m_lstIMDevice.Add(item);
                }

            }
            else
            {
                //其他设备最多
                int nCount = 0;
                int index = 0;
                Point2d pt = new Point2d(0, 0);

                if (nCountIM >= nCountOther)
                {//IM设备多，根据im设备计算图形最大长度和宽度
                    //路由设备，其他设备长度适应im设备
                     //计算多少个im设备或者设置一个router
                    nCount = (nCountIM + nRouterCount - 1) / nRouterCount;

                }
                else
                {
                    nCount = (nCountOther + nRouterCount - 1) / nRouterCount;
                }



                if (m_direction == _direction.TABLE_HOR)
                {//横向出图
                    pt += new Vector2d(0,-m_nDeletaWithRouter);
                }
                else
                {
                    pt += new Vector2d(-m_nDeletaWithRouter,0);
                }

                //计算im设备位置,作为基准设备
                for (index = 0; index < nCountIM; index++)
                {
                    _layout_item item = new _layout_item();

                    if (m_direction == _direction.TABLE_HOR)
                    {//横向出图
                        item.ptStart = pt;
                        item.nHeight = m_nDefaultHeight;
                        item.nWidth = m_nDefaultWidth;
                        pt += new Vector2d(m_nDefaultWidth + m_nDeletaDevice, 0);
                    }
                    else
                    {
                        //纵向出图，宽高相反
                        item.ptStart = pt;
                        item.nHeight = m_nDefaultWidth;
                        item.nWidth = m_nDefaultHeight;
                        pt -= new Vector2d(0, m_nDefaultWidth + m_nDeletaDevice);
                    }

                    m_lstIMDevice.Add(item);
                }

                pt = new Point2d(0, 0);

                if (m_direction == _direction.TABLE_HOR)
                {//横向出图
                    pt += new Vector2d(0,  2 * m_nDefaultHeight + m_nDeletaWithRouter);
                }
                else
                {
                    pt += new Vector2d(m_nDefaultHeight + m_nDeletaWithRouter, 0);
                }

                //计算other设备位置
                for (index = 0; index < nCountOther; index++)
                {
                    _layout_item item = new _layout_item();

                    if (m_direction == _direction.TABLE_HOR)
                    {//横向出图
                        item.ptStart = pt;
                        item.nHeight = m_nDefaultHeight;
                        item.nWidth = m_nDefaultWidth;
                        pt += new Vector2d(m_nDefaultWidth + m_nDeletaDevice, 0);
                    }
                    else
                    {
                        //纵向出图，宽高相反
                        item.ptStart = pt;
                        item.nHeight = m_nDefaultWidth;
                        item.nWidth = m_nDefaultHeight;
                        pt -= new Vector2d(0, m_nDefaultWidth + m_nDeletaDevice);
                    }

                    m_lstOtherDevice.Add(item);
                }


                pt = new Point2d(0, 0);

                if (m_direction == _direction.TABLE_HOR)
                {//横向出图
                    pt += new Vector2d(0, m_nDefaultHeight );
                }

                //计算路由设备位置
                for (index = 0; index < nRouterCount; index++)
                {
                    _layout_item item = new _layout_item();

                    if (m_direction == _direction.TABLE_HOR)
                    {//横向出图
                        int nNewWidth = nCount * m_nDefaultWidth + (nCount - 1) * m_nDeletaDevice;
                        item.ptStart = pt;
                        item.nHeight = m_nDefaultHeight;
                        item.nWidth = nNewWidth;
                        pt += new Vector2d(nNewWidth + m_nDeletaDevice,0);
                    }
                    else
                    {
                        //纵向出图，宽高相反
                        int nNewWidth = nCount * m_nDefaultWidth + (nCount - 1) * m_nDeletaDevice;
                        item.ptStart = pt;
                        item.nHeight = nNewWidth;
                        item.nWidth = m_nDefaultHeight;
                        pt -= new Vector2d(0, nNewWidth + m_nDeletaDevice);
                    }

                    m_lstRouter.Add(item);

                }


              }

            return true;
        }


    }
}
